module  digital_tube_matrix(
	input sys_rst,
	input sys_clk,
	input [3:0] key_id,
	output reg[5:0] leg_seg,
	output reg[7:0] led_bit
);

parameter DIGITAL_TUBE_FRESH_PERIOD = 24'd50000;					//系统频率50M , 500000/50M = 10ms，数码管刷新频率1KHZ
parameter DIGTIAL_TUBE_DIGITS = 3'd6;									//6位数码管
parameter KEY_HOLD_DETECT_PERIOD = 24'd10000000;					//系统频率50M , 10,000000/50M = 0.2S

reg [11:0] digital_num;

reg [7:0] led0_bits;
reg [7:0] led1_bits;
reg [7:0] led2_bits;
reg [7:0] led3_bits;
reg [7:0] led4_bits;
reg [7:0] led5_bits;

wire [3:0] led0_display_num;
wire [3:0] led1_display_num;
wire [3:0] led2_display_num;
wire [3:0] led3_display_num;
wire [3:0] led4_display_num;
wire [3:0] led5_display_num;

reg [2:0] digital_tube_selected;						//当前选项显示的数码管
reg [23:0] digital_tube_timer;						//数码管刷新周期
reg [3:0] current_display_num;						//当前显示的数码管显示值
reg		digit_tube_num_inc_flag;					//显示管位数加1标记
reg [31:0] key_press_hold_timer;

assign led0_display_num = digital_num % 4'd10;
assign led1_display_num = (digital_num / 4'd10) % 4'd10;
assign led2_display_num = (digital_num / 7'd100) % 4'd10;
assign led3_display_num = (digital_num / 10'd1000) % 4'd10;
assign led4_display_num = (digital_num / 14'd10000) % 4'd10;
assign led5_display_num = (digital_num / 17'd100000) % 4'd10;


/*数码管数字显示*/
always @(posedge sys_clk or negedge sys_rst)			begin	
	if (!sys_rst)	begin													//复位
		leg_seg <= 6'b0;
		led_bit  <= 8'b0;
	end
	else				begin
		leg_seg <=  ~(1 << digital_tube_selected);
		case (current_display_num)
			 4'h0 :    led_bit <= 8'b1100_0000;
            4'h1 :    led_bit <= 8'b1111_1001;
            4'h2 :    led_bit <= 8'b1010_0100;
            4'h3 :    led_bit <= 8'b1011_0000;
            4'h4 :    led_bit <= 8'b1001_1001;
            4'h5 :    led_bit <= 8'b1001_0010;
            4'h6 :    led_bit <= 8'b1000_0010;
            4'h7 :    led_bit <= 8'b1111_1000;
            4'h8 :    led_bit <= 8'b1000_0000;
            4'h9 :    led_bit <= 8'b1001_0000;
            4'ha :    led_bit <= 8'b1000_1000;
            4'hb :    led_bit <= 8'b1000_0011;
            4'hc :    led_bit <= 8'b1100_0110;
            4'hd :    led_bit <= 8'b1010_0001;
            4'he :    led_bit <= 8'b1000_0110;
            4'hf :    led_bit <= 8'b1000_1110;
				default: led_bit <= 8'b1100_0000;
		endcase
	end
end

/*按键控制显示值变化*/
always @(posedge sys_clk or negedge sys_rst) begin
	if (!sys_rst)	begin													//复位
		digital_num <= 24'd0;
		key_press_hold_timer <= 32'd0;
	end
	else if(key_id != 4'b0)							begin 			//检测到按键,显示值加1
		if (key_press_hold_timer < KEY_HOLD_DETECT_PERIOD - 1'b1)	begin
			key_press_hold_timer <= key_press_hold_timer + 1'b1;
		end
		else																		begin
			key_press_hold_timer <= 32'd0;
			digital_num <= digital_num + 1'b1;
		end
	end
	else													begin				//数据锁存
		digital_num <= digital_num; 
		key_press_hold_timer <= 32'd0;
	end
end

/*当前显示LED数码管显示值更新*/
always @(posedge sys_clk or negedge sys_rst ) begin 
	if (!sys_rst )			begin 		//复位
		current_display_num <= 3'b0;
	end
	else 						begin
		case (digital_tube_selected)
			3'd0: current_display_num <= digital_num[3:0];
			3'd1: current_display_num <= digital_num[7:4];
			3'd2: current_display_num <= digital_num[11:8];
			3'd3: current_display_num <= 4'd0;
			3'd4: current_display_num <= 4'd0;
			3'd5: current_display_num <= 4'd0;
			default:current_display_num <= 4'd0;
		endcase
	end
end

/*数码管动态显示位数控制*/
always @(posedge sys_clk or negedge sys_rst)							begin
	if (!sys_rst )																begin 		//复位
		digital_tube_selected <= 3'b0;
	end
	
	else if	(digit_tube_num_inc_flag == 1'b1)						begin
		if (digital_tube_selected < (DIGTIAL_TUBE_DIGITS - 1'b1))	begin
			digital_tube_selected <= digital_tube_selected + 1'b1;
		end
		else																		begin
			digital_tube_selected <= 3'b0;
		end
	end
	
	else																			begin			//显示位重0循环
		digital_tube_selected <=  digital_tube_selected;
	end
end

/*数码管动态显示刷新周期*/
always @(posedge sys_clk or negedge sys_rst)	begin
	if (!sys_rst)										begin			//复位
		digit_tube_num_inc_flag <= 1'b0;
		digital_tube_timer <= 24'd0;
	end
	else 	if (digital_tube_timer < DIGITAL_TUBE_FRESH_PERIOD -1'b1)	begin 
		digital_tube_timer <= digital_tube_timer + 1'b1;
		digit_tube_num_inc_flag <= 1'b0;
	end
	else													begin
		digital_tube_timer <= 24'd0;
		digit_tube_num_inc_flag <= 1'b1;
	end
end

endmodule